namespace Resharper.Abstractions.CodeDom.Expressions.AsOperatorExpressions
{
  using System.Diagnostics;
  using JetBrains.Annotations;
  using JetBrains.ReSharper.Psi.CSharp.Tree;
  using Resharper.Abstractions.CodeDom.Expressions.LiteralExpressions;

  /// <summary>Defines the <see cref="LiteralExpression"/> class.</summary>
  public class AsOperatorExpression : Expression
  {
    #region Constructors and Destructors

    /// <summary>Initializes a new instance of the <see cref="LiteralExpression"/> class.</summary>
    /// <param name="asExpression">The expression.</param>
    internal AsOperatorExpression([NotNull] IAsExpression asExpression) : base(asExpression)
    {
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets the right operand.
    /// </summary>
    [CanBeNull]
    public Expression Operand
    {
      get
      {
        var expression = this.InternalAsExpression.Operand;
        if (expression == null)
        {
          return null;
        }

        return ExpressionFactory.GetExpression(expression);
      }
      set
      {
        Debug.Assert(value != null, "value != null");

        this.InternalAsExpression.SetOperand((ICSharpExpression)value.InternalExpression);
      }
    }

    /// <summary>The literal expression field.</summary>
    [NotNull]
    internal IAsExpression InternalAsExpression
    {
      get
      {
        return (IAsExpression)this.InternalExpression;
      }
    }

    /// <summary>
    /// Gets the type operand.
    /// </summary>
    [NotNull]
    public string TypeOperand
    {
      get
      {
        var typeOperand = this.InternalAsExpression.TypeOperand;
        if (typeOperand == null)
        {
          return string.Empty;
        }

        return typeOperand.GetText();
      }
    }

    #endregion

    #region Public Methods

    /// <summary>
    /// Gets the operator sign text range.
    /// </summary>
    public bool OperatorSignContains(int offset)
    {
      var operatorSign = this.InternalAsExpression.OperatorSign;
      if (operatorSign == null)
      {
        return false;
      }

      var range = operatorSign.GetNavigationRange();

      return range.TextRange.Contains(offset);
    }

    #endregion
  }
}